package com.gsit.watcher;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.gsit.mailer.services.EmailServices;
import com.gsit.watcher.util.MediaPlayerUtil;
/**
 * 
 * 
 */
public class App {
	
	 private final static Logger log = LoggerFactory.getLogger(App.class);

	final private static Config config = Config.getInstance();
	private WebDriver driver = new FirefoxDriver();
	private static MediaPlayerUtil mediaPlayerUtil;
	
	private Integer minNumbOfNetlog = Integer.parseInt(config.getNetLogMinNumbOfPic());
	private Integer minNumbOfTwoo = Integer.parseInt(config.getTwooMinNumbOfPic());
	
	//for check netlog and twoo
	private Integer sizeOfAR=0;
	private Integer sizeOfNORMAL=0;
	private Integer sizeOfPROFILE=0;
	private Integer sizeOfPRIVATE=0;
	private Integer sizeOfPUBLIC=0;
	// measure total size
	
	private TwooDataHolder newTwoodataHolder = new TwooDataHolder();
	private TwooDataHolder oldTwoodataHolder = new TwooDataHolder();
	private NetlogDataHolder newNetlogDataHolder = new NetlogDataHolder();
	private NetlogDataHolder oldNetlogDataHolder = new NetlogDataHolder();
	static AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
	static{
		//ctx.register(AppConfig.class);
		ctx.refresh();
	}
	
	private Boolean isFirstUser = Boolean.FALSE;
	private Integer alaramCounter = 0;
	private Integer netLogCount = 0;
	private Integer twooCount = 0;

	public static void main(String[] args) {

		App app = new App();
		log.info("! App is started, Welcome to Netlog Watcher App ... provided by GSIT Research Lab ....");
		try {
			do {
				try{
					app.start();
				}catch(Exception e){
					log.error("! Error , The Syste will be back in 5 mnt");
					app.sleep(300000);
				}
			} while (true );
		} catch (Exception e) {
		} finally {
			app.stop();
			log.info("! App is stop");
			System.exit(0);
		}
	}

	private void start() {
		doLogin();
		sleep(1000);
		try {
			execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
		sleep(2000);
		doLogOff();
		//cog300000
		sleep(Long.parseLong(config.getPeriod()));
	}

	private void stop() {
		driver.quit();
	}

	private void execute() throws Exception {
		try {
			System.out.println("Net Log Min = "+minNumbOfNetlog);
			System.out.println("Twoo Log Min = "+minNumbOfTwoo);
			
			//netlog - start
			if (config.getQueuesToCheck().contains("NORMAL")) {
				log.info("NetLog NORMAL executing...");
				sizeOfNORMAL = getCaptureImageList(config.getNetlogURL(),
						config.getNetlogNormalURL(),
						oldNetlogDataHolder.getNormalList(),
						newNetlogDataHolder.getNormalList());
			}
			if (config.getQueuesToCheck().contains("AR")) {
				log.info("NetLog AR executing...");
				sizeOfAR = getCaptureImageList(config.getNetlogURL(), config.getNetlogARURL(),
						oldNetlogDataHolder.getARList(),
						newNetlogDataHolder.getARList());
			}
			
			if (config.getQueuesToCheck().contains("AR_STRICT")) {
				log.info("NetLog AR executing...");
				getCaptureImageList(config.getNetlogURL(),
						config.getNetlogARStrictURL(),
						oldNetlogDataHolder.getARStrictList(),
						newNetlogDataHolder.getARStrictList());
			}
			//netlog - end
			//twoo - start
			if (config.getQueuesToCheck().contains("PRIVATE")) {
				log.info("Twoo PRIVATE executing...");
				sizeOfPRIVATE = getCaptureImageList(config.getTwooURL(),
						config.getTwooPrivateURL(),
						oldTwoodataHolder.getPrivateList(),
						newTwoodataHolder.getPrivateList());
			}
			if (config.getQueuesToCheck().contains("PROFILE")) {
				log.info("Twoo PROFILE executing...");
				sizeOfPROFILE = getCaptureImageList(config.getTwooURL(),
						config.getTwooProfileURL(),
						oldTwoodataHolder.getProfileList(),
						newTwoodataHolder.getProfileList());
			}
			if (config.getQueuesToCheck().contains("PUBLIC")) {
				log.info("Twoo PUBLIC executing...");
				sizeOfPUBLIC = getCaptureImageList(config.getTwooURL(), config.getTwooPublicURL(),
						oldTwoodataHolder.getPublicList(),
						newTwoodataHolder.getPublicList());
			}
				try {
					checkNetLog(sizeOfAR, sizeOfNORMAL);
				} catch (Exception e) {
					log.info("checkNetLog called - Excepted Integer,but We got "+e);
				}
				try {
					checkTwoo(sizeOfPROFILE,sizeOfPRIVATE, sizeOfPUBLIC);
				} catch (Exception e) {
					log.info("checkTwoo called - Excepted Integer,but We got "+e);
				}
				if (netLogCount==3) {
					log.info("NetLogCount timer has reached 3,NetLog Site is down");
					processNetlogMail(sizeOfNORMAL, "name", newNetlogDataHolder.getNormalList());
				}
				if (twooCount==3) {
					log.info("TwooCount timer has reached 3,Twoo Site is down");
					processTwooMail(alaramCounter, "name", newTwoodataHolder.getProfileList());
				}
			//twoo - end
		} catch (Exception e) {
			procesSiteOffMail(alaramCounter, "Sys off", oldTwoodataHolder.getPublicList());
		}
		
	}

	public Integer getCaptureImageList(String sHomeURL, String sURL,
			List<String> oldList, List<String> newList) throws Exception {
		WebDriverWait wait = new WebDriverWait(driver, 30);
		driver.get(sHomeURL);
		wait = new WebDriverWait(driver, 30);
		driver.get(sURL);

		List<WebElement> images = driver.findElements(By.tagName("li"));
		for (WebElement table2 : images) {
			String hrfStr = table2.getAttribute("id");
			if (!hrfStr.isEmpty()) {
				newList.add(hrfStr);
			}
		}
		if (oldList == null || oldList.isEmpty()) {
			log.info("Old list is empty");
		} else if (oldList.size()!= 0) {
			log.info("Old list is not empty");
			Collection<String> similarList = new ArrayList<String>(newList);
			for (String newlist : newList) {
				log.info("New List >>> "+newlist);
			}
			similarList.retainAll(oldList);
			if (similarList.isEmpty()) {
				alaramCounter = 0;
				log.info("! Pictures Moved");
				oldList.clear();
			} else {
				log.info("! Same Pictures are found");
				alaramCounter++;
				log.info("! Alaram Triggred for "+alaramCounter);
				callPlayer();
				sleep(Long.parseLong(config.getAfterAlaram()));
				if(alaramCounter %3 ==0 ){
					processMail(alaramCounter,sURL,similarList);
				}
				oldList.clear();
			}
		}
		if (newList != null && newList.size() > 0) {
			oldList.addAll(newList);
			newList.clear();
		}
		log.info("Total number of pending image is : "+oldList.size());
		for (String imageName : oldList) {
			log.info("Image name is  : "+imageName);
		}
		return oldList.size();
	}

	private void doLogin() {
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yy 'at' HH:mm:ss");
		log.info("Login to your System , time " + dateFormat.format(new Date()));
		System.out.println("Login to your System , time " + dateFormat.format(new Date()));
		driver.get("http://photospy.netnoc.eu/login");
		WebElement element = driver.findElement(By.id("usernameText"));
		User user = null;
		if(isFirstUser){
			user = config.getFirstUser();
			isFirstUser= Boolean.FALSE;
		}else{
			user = config.getSecondUser();
			isFirstUser= Boolean.TRUE;
		}
		if (element != null) {
			element.sendKeys(user.getUserName());
		}
		element = driver.findElement(By.id("passwordText"));
		if (element != null) {
			element.sendKeys(user.getPassword());
		}
		element.submit();
	}

	private void doLogOff() {
		log.info("doLogOff call ");
		WebElement element = driver.findElement(By.linkText("Logout"));
		element.click();
	}

	private void sleep(long ms) {
		try {
			Thread.sleep(ms);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void callPlayer() throws Exception {
		mediaPlayerUtil = new MediaPlayerUtil();
		mediaPlayerUtil.createAndRun();
	}
	
	private void processMail(Integer alaramCounter, String sURL, Collection<String> similarList){
		log.info("! Mail is sending ");
		try {
			EmailServices emailServices = ctx.getBean(EmailServices.class);
			Map<String , Object> dataHolder =  new Hashtable<String, Object>();
			dataHolder.put("sURL",sURL);
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yy 'at' HH:mm:ss");
			dataHolder.put("incidentTime", dateFormat.format(new Date()));
			dataHolder.put("alaramCounter", alaramCounter);
			dataHolder.put("similarList", similarList);
			emailServices.process("vm.mail.sendmessage", dataHolder);
		} catch (Exception e) {
			
		}
	}
	
	private void processNetlogMail(Integer alaramCounter, String name, Collection<String> similarList){
		try {
			EmailServices emailServices = ctx.getBean(EmailServices.class);
			Map<String , Object> dataHolder =  new Hashtable<String, Object>();
			dataHolder.put("sURL",name);
			emailServices.process("vm.mail.netlog", dataHolder);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void procesSiteOffMail(Integer alaramCounter, String name, Collection<String> similarList){
		try {
			EmailServices emailServices = ctx.getBean(EmailServices.class);
			Map<String , Object> dataHolder =  new Hashtable<String, Object>();
			dataHolder.put("sURL",name);
			emailServices.process("vm.mail.siteOff", dataHolder);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void processTwooMail(Integer alaramCounter, String name, Collection<String> similarList){
		try {
			EmailServices emailServices = ctx.getBean(EmailServices.class);
			Map<String , Object> dataHolder =  new Hashtable<String, Object>();
			dataHolder.put("sURL",name);
			emailServices.process("vm.mail.twoo", dataHolder);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	private void checkNetLog(Integer sizeOfAR,Integer sizeOfNORMAL){
		log.info("SizeOfAR >>> "+sizeOfAR+"\t"+"SizeOfNORMAL >>> "+sizeOfNORMAL);
		log.info("Netlog Count is "+twooCount);
		if (sizeOfAR < minNumbOfNetlog && sizeOfNORMAL < minNumbOfNetlog ) {
			netLogCount++;
		}else{
			netLogCount = 0;
		}
	}
	private void checkTwoo(Integer sizeOfPROFILE,Integer sizeOfPRIVATE,Integer sizeOfPUBLIC){
		log.info("sizeOfPROFILE >>> "+sizeOfPROFILE+"\t"+"SizeOfPRIVATE >>> "+sizeOfPRIVATE+"\t"+"SizeOfPUBLIC >>> "+sizeOfPUBLIC);
		log.info("Twoo Count is "+twooCount);
		if (sizeOfPROFILE < minNumbOfTwoo && sizeOfPRIVATE  < minNumbOfTwoo && sizeOfPUBLIC < minNumbOfTwoo ) {
			processTwooMail(alaramCounter, "name", newNetlogDataHolder.getNormalList());
			twooCount++;
		}else{
			twooCount = 0;
		}
		}
	}
